/*
*	File: CoreSubMesh.h
*	Date: 12/18/2011
*	Author: Ivan Gao
*	Desc:
*/
#ifndef CORESUBMESH_H_
#define CORESUBMESH_H_
#include "CommonDef.h"
#include "Vector.h"
#include <vector>
using namespace std;
class SCoreSubMorphTarget;
enum SMorphTargetType
{
	SMTT_NONE,
	SMTT_ADDITVIE,
	SMTT_CLAMPED,
	SMTT_AVERAGE,
	SMTT_EXCLUSIVE,
};

class SIMPLEANIMATION_API SCoreSubMesh
{
public:
	struct TextureCoordinate
	{
		float u, v;
	}; // TextureCoordinate

	struct TangentSpace
	{
		SVector3 tangent;
		float crossFactor;  // To get the binormal, use ((N x T) * crossFactor)
	}; // TangentSpace

	struct Influence 
	{
		int nBoneId;
		float weight;
	}; // Influence

	struct PhysicalProperty
	{
		float weight;
	}; // PhysicalProperty

	struct Vertex
	{
		SVector3	positon;
		SVector3	normal;
		vector<Influence> vectorInfluence;
		int			nCollapseId;
		int			nFaceCollapseCount;
		SVector3	vertexColor;
	}; // Vertex

	struct Face
	{
		SVertexIndex vertexIndex[3];
	}; // Face

	struct Spring
	{
		int		nVertexId[2];
		float	springCoefficient;
		float	idleLength;
	}; // Spring

public:
	SCoreSubMesh ();
	~SCoreSubMesh ();
	int GetCoreMaterialThreadId () const;
	int GetFaceCount () const;
	typedef vector<SCoreSubMorphTarget *> SCoreSubMorphTargetVector;
	typedef vector<Face> SFaceVector;
	typedef vector<PhysicalProperty> SPhysicalPropertyVector;
	typedef vector<Spring> SSpringVector;
	typedef vector<TangentSpace> STangentSpaceVector;
	typedef vector<TextureCoordinate> STextureCoordinateVector;
	typedef vector<STangentSpaceVector> STangentSpaceVectorVector;
	typedef vector<STextureCoordinateVector> STextureCoordinateVectorVector;
	typedef vector<Vertex> SVertexVector;
	typedef vector<Influence> SInfluenceVector;

	int GetLodCount (void) const;
	int GetSpringCount (void) const;
	bool HaveNonWhiteVertexColors (void);
	SFaceVector & GetFaceVector (void);
	const SFaceVector & GetFaceVector (void) const;
	SPhysicalPropertyVector & GetPhysicalPropertyVector (void);
	const SPhysicalPropertyVector & GetPhysicalPropertyVector (void) const;
	SSpringVector & GetSpringVector (void);
	const SSpringVector & GetSpringVector (void) const;
	STangentSpaceVectorVector & GetTangentSpaceVectorVector (void);
	const STangentSpaceVectorVector & GetTangentSpaceVectorVector (void) const;
	STextureCoordinateVectorVector & GetTextureCoordinateVectorVector (void);
	const STextureCoordinateVectorVector & GetTextureCoordinateVectorVector (void) const;
	SVertexVector & GetVertexVector (void);
	const SVertexVector & GetVertexVector (void) const;
	int GetVertexCount (void) const;
	bool IsTangentEnabled (int nMapId) const;
	bool EnableTangents (int nMapId, bool bEnable);
	bool Reserve (int nVertexCount, int nTextureCoordinateCount, int nFaceCount, int nSpringCount);
	void SetCoreMaterialThreadId (int nCoreMaterialThreadId);
	bool SetFace (int nFaceId, const Face & face);
	void SetLodCount (int nLodCount);
	bool SetPhysicalProperty (int nVertexId, const PhysicalProperty & rProperty);
	bool SetSpring (int nSpringId, const Spring & rSpring);
	bool SetTextureCoordinate (int nVertexId, int nTextureId, const TextureCoordinate & rTC);
	bool SetVertex (int nVertexId, const Vertex & rVertex);
	bool SetTangentSpace (int nVertexId, int nMapId, const SVector3 & tangent, float crossFactor);
	inline bool SetHaveNonWhiteVertexColors (bool bHaveNonWhite)
	{
		m_bHaveNonWhiteVertexColors = bHaveNonWhite;
	} // SetHaveNonWhiteVertexColors
	int AddCoreSubMorphTarget (SCoreSubMorphTarget * pCoreSubMorphTarget);


	SCoreSubMorphTarget * GetCoreSubMorphTarget (int nId);
	const SCoreSubMorphTarget * GetCoreSubMorphTarget (int nId) const;
	int GetCoreSubMorphTargetCount () const;
	SCoreSubMorphTargetVector & GetCoreSubMorphTargetVector ();
	const SCoreSubMorphTargetVector & GetCoreSubMorphTargetVector () const;
	void Scale (float scale);
	void SetSubMorphTargetGroupIndexArray (int nLen, const int * pIndexArray);
	int GetSubMorphTargetGroupIndex (int nSubMorphTargetId);

private:
	void							UpdateTangentVector (int v0, int v1, int v2, int nChannel);
	SVertexVector					m_vecVertex;
	vector<bool>					m_vecTangentsEnabled;
	STangentSpaceVectorVector		m_vecvecTangentSpace;
	STextureCoordinateVectorVector	m_vecvecTextureCoordinate;
	SPhysicalPropertyVector			m_vecPhysicalProperty;
	SFaceVector						m_vecFace;
	SSpringVector					m_vecSpring;
	SCoreSubMorphTargetVector		m_vecCoreSubMorphTarget;
	int								m_nCoreMaterialThreadId;
	int								m_nLodCount;
	vector<int>						m_vecSubMorphTargetGroupIndex;
	bool	m_bHaveNonWhiteVertexColors;
}; // SCoreSubMesh
#endif // CORESUBMESH_H_